package com.atguigu.dga.lineage.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.dga.lineage.bean.GovernanceLineageTable;
import com.atguigu.dga.lineage.service.GovernanceLineageTableService;
import com.atguigu.dga.meta.bean.TableMetaInfo;
import com.atguigu.dga.meta.service.TableMetaInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zhangchen
 * @since 2023-11-27
 */
@RestController
@RequestMapping("/lineage")
public class GovernanceLineageTableController {

    @Autowired
    GovernanceLineageTableService governanceLineageTableService;

    @Autowired
    TableMetaInfoService tableMetaInfoService;

    @GetMapping("/root/{tableName}")
    public  String getRoot(@PathVariable("tableName")String tableNameWithSchema){
        //查询该表的血缘关系对象
        String[] tableWithSchemaNameArr = tableNameWithSchema.split("\\.");
        QueryWrapper<GovernanceLineageTable> queryWrapper = new QueryWrapper<GovernanceLineageTable>().eq("schema_name", tableWithSchemaNameArr[0])
                .eq("table_name", tableWithSchemaNameArr[1])
                .inSql("governance_date", "select max(governance_date) from governance_lineage_table");

        GovernanceLineageTable governanceLineageTable = governanceLineageTableService.getOne(queryWrapper);

        // 提取所有表的元数据  目的：获得表名备注
        List<TableMetaInfo> tableMetaInfoWithExtraList = tableMetaInfoService.getTableMetaInfoWithExtraList(governanceLineageTable.getGovernanceDate());
        Map<String, TableMetaInfo> tableMetaInfoMap = tableMetaInfoWithExtraList.stream().collect(Collectors.toMap(tableMetaInfo -> tableMetaInfo.getSchemaName() + "." + tableMetaInfo.getTableName(), tableMetaInfo -> tableMetaInfo));

        // 封装根节点数据
        JSONObject rootJsonObj = new JSONObject();
        rootJsonObj.put("isRoot",true);

        TableMetaInfo tableMetaInfo = tableMetaInfoMap.get( tableNameWithSchema );
        rootJsonObj.put("comment",tableMetaInfo.getTableComment());
        rootJsonObj.put("id",tableNameWithSchema);

        //准备子节点集合
        List<JSONObject> childrenList = new ArrayList<>();
        //先插入来源表

        String sourceTableJson = governanceLineageTable.getSourceTables();
        List<String> sourceTableNameList = JSON.parseArray(sourceTableJson, String.class);
        if(sourceTableNameList!=null){
            for (String sourceTableName : sourceTableNameList) {
                JSONObject sourceJsonObj = new JSONObject();
                sourceJsonObj.put("id",sourceTableName);
                sourceJsonObj.put("relation","source");
                TableMetaInfo sourceTableMetaInfo = tableMetaInfoMap.get(sourceTableName);
                sourceJsonObj.put("comment",sourceTableMetaInfo.getTableComment());
                childrenList.add(sourceJsonObj);
            }
        }


        //再出入输出表
        String sinkTables = governanceLineageTable.getSinkTables();
        List<String> sinkTableNameList = JSON.parseArray(sinkTables, String.class);
        if(sinkTableNameList!=null) {
            for (String sinkTableName : sinkTableNameList) {
                JSONObject sinkJsonObj = new JSONObject();
                sinkJsonObj.put("id", sinkTableName);
                sinkJsonObj.put("relation", "sink");
                TableMetaInfo sourceTableMetaInfo = tableMetaInfoMap.get(sinkTableName);
                sinkJsonObj.put("comment", sourceTableMetaInfo.getTableComment());
                childrenList.add(sinkJsonObj);
            }
        }

        rootJsonObj.put("children",childrenList);

        return rootJsonObj.toJSONString();
    }

    @GetMapping("/child/{tableName}")
    public  String getChildren(@PathVariable("tableName")String tableNameWithSchema, @RequestParam("relation") String relation){
        //1 有括号的表(有括号，是页面因为避免表名重复而增加的后缀，去掉括号部分
        if(tableNameWithSchema.indexOf("(")>0){
            int suffixIdx = tableNameWithSchema.indexOf("(");
            tableNameWithSchema=tableNameWithSchema.substring(0,suffixIdx);

        }


        //查询该表的血缘关系对象
        String[] tableWithSchemaNameArr = tableNameWithSchema.split("\\.");
        QueryWrapper<GovernanceLineageTable> queryWrapper = new QueryWrapper<GovernanceLineageTable>().eq("schema_name", tableWithSchemaNameArr[0])
                .eq("table_name", tableWithSchemaNameArr[1])
                .inSql("governance_date", "select max(governance_date) from governance_lineage_table");

        GovernanceLineageTable governanceLineageTable = governanceLineageTableService.getOne(queryWrapper);

        // 提取所有表的元数据  目的：获得表名备注
        List<TableMetaInfo> tableMetaInfoWithExtraList = tableMetaInfoService.getTableMetaInfoWithExtraList(governanceLineageTable.getGovernanceDate());
        Map<String, TableMetaInfo> tableMetaInfoMap = tableMetaInfoWithExtraList.stream().collect(Collectors.toMap(tableMetaInfo -> tableMetaInfo.getSchemaName() + "." + tableMetaInfo.getTableName(), tableMetaInfo -> tableMetaInfo));


        // 准备childlist
        List<JSONObject> childrenList = new ArrayList<>();
        String childTables=null;
        if(relation.equals("source")){
            childTables = governanceLineageTable.getSourceTables();
        }else{
            childTables = governanceLineageTable.getSinkTables();
        }
        List<String> childTableNameList  = JSON.parseArray(childTables, String.class);
        if(childTableNameList!=null) {
            for (String sinkTableName : childTableNameList) {
                JSONObject sinkJsonObj = new JSONObject();
                sinkJsonObj.put("id", sinkTableName);
                sinkJsonObj.put("relation", relation);
                TableMetaInfo sourceTableMetaInfo = tableMetaInfoMap.get(sinkTableName);
                sinkJsonObj.put("comment", sourceTableMetaInfo.getTableComment());
                childrenList.add(sinkJsonObj);
            }
        }

        return JSON.toJSONString(childrenList);
    }

}
